package com.scs.application.core.utils;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ Description：数字操作，加减乘除等
 */
public class UtilNum {
    /**
     * double 相加
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double sum(Object d1, Object d2) {
        BigDecimal bd1 = new BigDecimal(getDouble(d1));
        BigDecimal bd2 = new BigDecimal(getDouble(d2));
        return getDouble(bd1.add(bd2).doubleValue());
    }


    /**
     * double 相减  d1-d2
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double sub(Object d1, Object d2) {
        BigDecimal bd1 = new BigDecimal(getDouble(d1));
        BigDecimal bd2 = new BigDecimal(getDouble(d2));
        return getDouble(bd1.subtract(bd2).doubleValue());
    }

    /**
     * double 乘法
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double mul(Object d1, Object d2) {
        BigDecimal bd1 = new BigDecimal(getDouble(d1));
        BigDecimal bd2 = new BigDecimal(getDouble(d2));
        return getDouble(bd1.multiply(bd2).doubleValue());
    }


    /**
     * double 除法
     *
     * @param d1
     * @param d2
     * @param scale 四舍五入 小数点位数
     * @return
     */
    public static double div(double d1, double d2, int scale) {
        //  当然在此之前，你要判断分母是否为0，
        //  为0你可以根据实际需求做相应的处理
        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return getDouble(bd1.divide(bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue());
    }

    /**
     * double 转 string 去掉后面锝0
     *
     * @param i
     * @return
     */
    public static String getString(double i) {
        String s = String.valueOf(i);
        if (s.indexOf(".") > 0) {
            //正则表达
            s = s.replaceAll("0+?$", "");//去掉后面无用的零
            s = s.replaceAll("[.]$", "");//如小数点后面全是零则去掉小数点
        }
        return s;
    }


    /**
     * string 转换成double，保留4位小数
     * @param Object 数字字符串
     * @return  isBlank|| "null" 返回0
     */
    public static double getDouble(Object param) {
        if (UtilCommon.strIsNull(param +"")) {
            return  0d;
        }
        String str;
        if (param instanceof Integer) {
            str= ((Integer)param).toString();
        }else if (param instanceof Double) {
            str= ((Double)param).toString();
        } else if (param instanceof Float) {
            str= ((Float)param).toString();
        } else if (param instanceof Long) {
            str= ((Long)param).toString();
        }else if (param instanceof BigDecimal) {
            str= ((BigDecimal)param).toString();
        }else{
            str=((String)param);
        }
        if(StringUtils.isBlank(str) || "null".equalsIgnoreCase(str)) return 0;
        BigDecimal   b   =   new   BigDecimal(str);
        double   f1   =   b.setScale(4,   BigDecimal.ROUND_HALF_UP).doubleValue();
        return  f1;
    }

    /**
    * @Description：判断是否是整数
     * <pre>
     *     以下都为false
     *     null，"null"，""，1.2,0.0
     * </pre>
    */
    public static boolean isInt(Object obj){
        String str=String.valueOf(obj);
        if(StringUtils.isBlank(str)) return false;
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    /**
     *使用精确小数BigDecimal
     */
    public void decimal4(String f) {
        BigDecimal bg = new BigDecimal(f);
        /**
         * 参数：
         newScale - 要返回的 BigDecimal 值的标度。
         roundingMode - 要应用的舍入模式。
         返回：
         一个 BigDecimal，其标度为指定值，其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。
         */
        double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        System.out.println(f1);
    }



    public static void main(String[] args) {
//        System.out.println(sum(null,null));
//        System.out.println(sum(1.012,null));
//        System.out.println(sub(0.1,null));
//        System.out.println(sub(null,0.1));
//        System.out.println(sub(null,1));
//        System.out.println(isInt(null));
//        System.out.println(isInt("null"));
//        System.out.println(isInt(""));
//        System.out.println(isInt(0.1));
//        System.out.println(isInt(1.5));
//        System.out.println(isInt(0.0));
//        System.out.println(isInt(0));
//        System.out.println(0.0 == 0);
        System.out.println(UtilNum.trimZero(new Double(("1.230"))));
        System.out.println(UtilNum.trimZero(new Double(("1.000"))));
        System.out.println(UtilNum.trimZero(new Double(("1.000"))));
    }

    /**
     * 数字转换为千位符
     *
     * @param number
     * @return
     */
    public static String numberToBits(String number) {
        String begin = "";
        String end = "";
        String[] num = number.split("\\.");
        if (num.length > 1) {
            begin = num[0];
            end = num[1];
        } else {
            begin = number;
        }
        return begin.replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ",") + "." + end;
    }

    /**
    * @Description：是否正整数
    */
    public static boolean isPureDigital(String str) {
        if (str == null || "".equals(str)){
            return false;
        }
        Pattern p;
        Matcher m;
        p = Pattern.compile("[0-9]*");
        m = p.matcher(str);
        if (m.matches()){
            return true;
        }else{
            return false;
        }
    }

    //去除右侧的0，会先格式化成4位小数
    public static String trimZero(Object s) {
        BigDecimal value = new BigDecimal(getDouble(s));
        value=value.setScale(4,BigDecimal.ROUND_HALF_UP);
        //去除多余0
        BigDecimal noZeros = value.stripTrailingZeros();
        return noZeros.toPlainString();
    }

    /**
     * 四捨五入，保留n位小數,不足位數补零
     * @param d 数值
     * @param scale 位数
     * @return
     */
    public static String toDecimal(Double d,int scale){
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The   scale   must   be   a   positive   integer   or   zero");
        }
        if(scale == 0){
            return new DecimalFormat("0").format(d);
        }
        String formatStr = "0.";
        for(int i=0;i<scale;i++){
            formatStr = formatStr + "0";
        }
        return new DecimalFormat(formatStr).format(d);
    }

    /***
     * @param number
     * @return: boolean
     * @Author: Tai
     * @date: 2024/4/24
     * @Description:  判断字符串是否为数字(包括小数）
     */
    public static boolean isNumber(String number){
        if (com.scs.application.core.utils.StringUtils.isBlank(number)) {
            return false;
        }
        try {
            Double.parseDouble(number);
            return true;
        } catch(Exception e){
            return false;
        }
    }

    /**
     * 计算小数位数
     * @param val
     * @return
     */
    public static int calcDecimalNum(String val) {
        if (com.scs.application.core.utils.StringUtils.isBlank(val)) {
            return 0;
        }
        String[] num = val.split("\\.");
        if (num.length == 2) {
            return num[1].length();
        }else {
            return 0;
        }
    }

    /**
     * 获取excel数值格式
     * @param val
     * @return
     */
    public static String getNumCellFormat(String val) {
        int num = calcDecimalNum(val);
        if (num == 0) {
            return "0_ ";
        }

        String formatStr = "0.";
        for(int i=0;i<num;i++){
            formatStr = formatStr + "0";
        }
        formatStr += "_ ";
        return formatStr;
    }

    /**
     * 将数字转换成以万为单位或者以亿为单位，因为在前端数字太大显示有问题
     *
     * @param amount 报销金额
     * @return
     * @author
     * @version 1.00.00
     * @date 2018年1月18日
     */
    private static final Double MILLION = 10000.0;
    private static final Double MILLIONS = 1000000.0;
    private static final Double BILLION = 100000000.0;
    private static final String MILLION_UNIT = "万";
    private static final String BILLION_UNIT = "亿";
    public static String amountConversion(double amount) {
        //最终返回的结果值
        String result = String.valueOf(amount);
        //四舍五入后的值
        double value = 0;
        //转换后的值
        double tempValue = 0;
        //余数
        double remainder = 0;

        //金额大于1百万小于1亿
        if (amount > MILLIONS && amount < BILLION) {
            tempValue = amount / MILLION;
            remainder = amount % MILLION;

            //余数小于5000则不进行四舍五入
            if (remainder < (MILLION / 2)) {
                value = formatNumber(tempValue, 2, false);
            } else {
                value = formatNumber(tempValue, 2, true);
            }
            //如果值刚好是10000万，则要变成1亿
            if (value == MILLION) {
                result = zeroFill(value / MILLION) + BILLION_UNIT;
            } else {
                result = zeroFill(value) + MILLION_UNIT;
            }
        }
        //金额大于1亿
        else if (amount > BILLION) {
            tempValue = amount / BILLION;
            remainder = amount % BILLION;

            //余数小于50000000则不进行四舍五入
            if (remainder < (BILLION / 2)) {
                value = formatNumber(tempValue, 2, false);
            } else {
                value = formatNumber(tempValue, 2, true);
            }
            result = zeroFill(value) + BILLION_UNIT;
        } else {
            result = zeroFill(amount);
        }
        return result;
    }

    /**
     * 对数字进行四舍五入，保留2位小数
     *
     * @param number   要四舍五入的数字
     * @param decimal  保留的小数点数
     * @param rounding 是否四舍五入
     * @return
     * @author
     * @version 1.00.00
     * @date 2018年1月18日
     */
    public static Double formatNumber(double number, int decimal, boolean rounding) {
        BigDecimal bigDecimal = new BigDecimal(number);

        if (rounding) {
            return bigDecimal.setScale(decimal, RoundingMode.HALF_UP).doubleValue();
        } else {
            return bigDecimal.setScale(decimal, RoundingMode.DOWN).doubleValue();
        }
    }

    /**
     * 对四舍五入的数据进行补0显示，即显示.00
     *
     * @return
     * @author
     * @version 1.00.00
     * @date 2018年1月23日
     */
    public static String zeroFill(double number) {
        String value = String.valueOf(number);

        if (value.indexOf(".") < 0) {
            value = value + ".00";
        } else {
            String decimalValue = value.substring(value.indexOf(".") + 1);

            if (decimalValue.length() < 2) {
                value = value + "0";
            }
        }
        return value;
    }

}
